package com.dem.javatestwebsocket.chathandler;

import cn.hutool.json.JSONUtil;
import com.dem.javatestwebsocket.mapper.ChatHistoryMapper;
import com.dem.javatestwebsocket.model.ChatHistory;
import com.dem.javatestwebsocket.service.impl.MessageRankService;
import com.dem.javatestwebsocket.service.impl.OnlineUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Date;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

@ServerEndpoint("/chat")
@Component
@Slf4j
public class Chat3Endpoint {


    private static OnlineUserService onlineUserService;
    private static MessageRankService messageRankService;
    private static MessageBroadcaster broadcaster;

    private static ChatHistoryMapper chatHistoryMapper;

    @Autowired
    public void setChatHistoryMapper(ChatHistoryMapper chatHistoryMapper) {
        Chat3Endpoint.chatHistoryMapper = chatHistoryMapper;
    }

    @Autowired
    public void setServices(OnlineUserService onlineUserService,
                            MessageRankService messageRankService,
                            MessageBroadcaster broadcaster) {
        Chat3Endpoint.onlineUserService = onlineUserService;
        Chat3Endpoint.messageRankService = messageRankService;
        Chat3Endpoint.broadcaster = broadcaster;
    }

    @OnOpen
    public void onOpen(Session session) {
        System.out.println("连接建立: " + session.getId());
        String userId = extractUserId(session);
        if (userId != null) {
            onlineUserService.userLogin(userId);
            sendOnlineUsersUpdate();
            broadcaster.addSession(session); // 添加会话
        } else {
            System.err.println("无法从会话中提取 userId");
        }
    }

    @OnMessage
    public void onMessage(String message, Session session) {
        try {
            // 解析消息
            ChatHistory chatHistory = JSONUtil.toBean(message, ChatHistory.class);
            chatHistory.setTime(new Date());

            // 提取用户 ID
            String userId = extractUserId(session);
            if (userId == null) {
                System.err.println("无法提取 userId");
                return;
            }

            // 持久化消息到数据库
            chatHistoryMapper.insert(chatHistory);

            // 更新消息排行榜
            messageRankService.incrementMessageCount(userId);

            // 通过 Redis 广播消息
            broadcaster.broadcast(JSONUtil.toJsonStr(chatHistory));
        } catch (Exception e) {
            System.err.println("处理消息时发生错误: " + e.getMessage());
            e.printStackTrace();
            sendError(session, "Error: An unexpected error occurred while processing the message.");
        }
    }

    @OnClose
    public void onClose(Session session) {
        String userId = extractUserId(session);
        if (userId != null) {
            onlineUserService.userLogout(userId);
            sendOnlineUsersUpdate();
        }
        broadcaster.removeSession(session); // 移除会话
        System.out.println("连接关闭: " + session.getId());
    }

    @OnError
    public void onError(Session session, Throwable throwable) {
        System.err.println("发生错误: " + session.getId());
        throwable.printStackTrace();
        sendError(session, "Error: An unexpected error occurred.");
    }

    private String extractUserId(Session session) {
        if (session == null || session.getRequestURI() == null) {
            return null;
        }
        String query = session.getRequestURI().getQuery();
        if (query == null || !query.contains("=")) {
            return null;
        }
        String[] pairs = query.split("&");
        for (String pair : pairs) {
            String[] keyValue = pair.split("=");
            if (keyValue.length == 2 && "userId".equals(keyValue[0])) {
                return keyValue[1];
            }
        }
        return null;
    }

    private void sendOnlineUsersUpdate() {
        Set<String> users = onlineUserService.getOnlineUsers();
        broadcaster.broadcast("ONLINE_USERS:" + String.join(",", users));
    }

    private void sendError(Session session, String errorMessage) {
        if (session != null && session.isOpen()) {
            try {
                session.getBasicRemote().sendText(errorMessage);
            } catch (IOException e) {
                System.err.println("发送错误消息时发生异常: " + e.getMessage());
                e.printStackTrace();
            }
        }
    }
}